Windy City Weapon Stats

Tier 1 Weapons
Level 5
★★★
\n
\n `).join(''); } // Drug data for drug randomizer // Build drug pools straight from the DRUGS array used by the Drugs section const ALL_DRUGS = (Array.isArray(window.DRUGS) ? window.DRUGS : []).map(d => ({ name: d.name, src: d.src, tier: d.tier || 't1' })); // Until tiers exist on DRUGS, treat both T1 and T2 as the full list so the randomizer always uses the Drugs section items. const t1Drugs = ALL_DRUGS; const t2Drugs = ALL_DRUGS; function getDrugPool() { const select = document.getElementById('drug-randomize-tier-select'); const chosen = select ? select.value : 'Any'; if (chosen === 'Tier 1') return t1Drugs; if (chosen === 'Tier 2') return t2Drugs; return ALL_DRUGS; } function spinDrugs() { const tier = document.getElementById('drug-randomize-tier-select')?.value || 't1'; // Build from the rendered Drugs grid: pull the actual drug name from the badge const cards = Array.from(document.querySelectorAll('#drugs .drug-grid .drug-card')); let all = cards.map(c => { const badge = c.querySelector('.drug-badge'); // drug name const name = (badge?.textContent || '').trim(); const img = c.querySelector('img')?.src || ''; return { name, src: img }; }).filter(d => d.name); // De‑dupe by name (pool, not results) const seen = new Set(); all = all.filter(d => (seen.has(d.name) ? false : (seen.add(d.name), true))); // Fallback to DRUGS array if grid hasn't rendered yet if (!all.length && Array.isArray(window.DRUGS)) { all = window.DRUGS.filter(d => d && d.name).map(d => ({ name: d.name, src: d.src || '' })); } // Optional tier filtering if items have a 'tier' ('t1'/'t2') let pool = all; if (all.length && typeof all[0] === 'object' && 'tier' in all[0]) { if (tier === 't2') { pool = all.filter(d => String(d.tier).toLowerCase() === 't2'); } else { pool = all.filter(d => String(d.tier).toLowerCase() === 't1' || !d.tier); } if (!pool.length) pool = all; } // Keep your original spin counts let count = (tier === 't2') ? Math.floor(Math.random() * 81) + 100 // 100–180 : Math.floor(Math.random() * 26) + 75; // 75–100 // Spin and aggregate counts per drug const counts = Object.create(null); for (let i = 0; i < count; i++) { const idx = Math.floor(Math.random() * pool.length); const name = pool[idx]?.name || 'Unknown'; counts[name] = (counts[name] || 0) + 1; } // Render as "Name xN" lines, sorted by highest quantity first const out = document.getElementById('drug-spin-result'); if (out) { const rows = Object.entries(counts) .sort((a,b) => b[1] - a[1]) .map(([name, qty]) => `
  • ${name} x${qty}
  • `) .join(''); out.innerHTML = '
      ' + rows + '
    '; } } function closeLightbox(){ document.getElementById('lightbox').classList.add('hidden'); } document.addEventListener('click', function(e){ if(e.target && e.target.id === 'lightbox-close') closeLightbox(); if(e.target && e.target.classList && e.target.classList.contains('lightbox-backdrop')) closeLightbox(); }); document.addEventListener('keydown', function(e){ if(e.key === 'Escape') closeLightbox(); }); function wireLightbox(){ // grid cards document.querySelectorAll('#tier1 .weapon-grid .weapon').forEach(card => { const img = card.querySelector('img'); const name = (card.querySelector('.name-badge')?.textContent || img?.alt || '').trim(); if(img){ img.style.cursor = 'zoom-in'; img.addEventListener('click', (ev)=>{ ev.stopPropagation(); openLightbox(img.src, name); }); } }); // randomizer results document.querySelectorAll('#spin-result .weapon').forEach(card => { const img = card.querySelector('img'); const name = (card.querySelector('.stats strong')?.textContent || img?.alt || '').trim(); if(img){ img.style.cursor = 'zoom-in'; img.addEventListener('click', (ev)=>{ ev.stopPropagation(); openLightbox(img.src, name); }); } }); } document.addEventListener('DOMContentLoaded', wireLightbox); // ---- CS:GO style reel spin ---- function buildPool(tier){ const pool = []; if(tier === 'tier2' && (typeof t2Weapons !== 'undefined') && t2Weapons.length){ // weight slightly, but if empty fallback to t1 const wt = t2Weapons.length < 5 ? 3 : 2; t2Weapons.forEach(w=>{ for(let i=0;i{ for(let i=0;i<3;i++) pool.push({...w}); }); } return pool; } function casePool(tier){ const raw = casePool_raw(tier); return weightedPoolFrom(raw); } function pickRandom(pool){ return pool[Math.floor(Math.random()*pool.length)]; } // ---- Multi-reel CS:GO style spins ---- function computeReelCount(tier){ if(tier === 'test') return 2; if(tier === 'tier1') return 4; if(tier === 'tier2') return 6; // change if you want return 2; } function createReelEl(sizeClass){ const wrap = document.createElement('div'); wrap.className = 'csgo-wrap ' + (sizeClass || 'single'); wrap.innerHTML = `
    `; return wrap; } function poolForTier(tier){ const pool = []; // If tier2 selected and we have any t2 items, include them weighted higher if(tier === 'tier2' && typeof t2Weapons !== 'undefined' && t2Weapons.length){ t2Weapons.forEach(w=>{ for(let i=0;i<3;i++) pool.push({...w}); }); } // Always include T1 pool as base so "any weapons" can appear if(typeof t1Weapons !== 'undefined' && t1Weapons.length){ t1Weapons.forEach(w=>{ for(let i=0;i<2;i++) pool.push({...w}); }); } return pool; } function casePool(tier){ const raw = casePool_raw(tier); return weightedPoolFrom(raw); } function pick(pool){ return pool[Math.floor(Math.random()*pool.length)]; } async function spinCSGO(){ const tier = document.getElementById('randomize-tier-select').value; const reelsWrap = document.getElementById('csgo-container'); const winnersWrap = document.getElementById('csgo-winners'); if(!reelsWrap) return; reelsWrap.querySelectorAll('.csgo-wrap').forEach(e=>e.remove()); winnersWrap.innerHTML = ''; const count = computeReelCount(tier); const pool = poolForTier(tier); const avoidDupes = true; if(!pool.length){ winnersWrap.textContent = 'No items available.'; return; } const reels = []; for(let i=0;i= 4 ? 'small' : 'single'); const reel = reelEl.querySelector('.csgo-reel'); reelsWrap.prepend(reelEl); // add before winners div reels.push({wrap: reelEl, reel, chosen: null}); } const tiles = 100; const cardW = 102; const durationBase = 2600; reels.forEach((r, idx)=>{ // Build tiles r.reel.innerHTML = ''; let chosenIdx = Math.floor(tiles*0.7 + Math.random()*20); let chosenW = null; for(let i=0;i0? chosenW?.name : null), avoidDupes); if(i === chosenIdx) chosenW = w; const card = document.createElement('div'); card.className = 'csgo-card ' + (w.tier && w.tier.startsWith('Tier 2') ? 't2':'t1'); const img = document.createElement('img'); img.src = w.img || ''; img.alt = w.name || ''; img.style.cursor = 'zoom-in'; img.addEventListener('click', (ev)=>{ ev.stopPropagation(); openLightbox(img.src, w.name); }); const nm = document.createElement('div'); nm.className = 'name'; nm.textContent = w.name || ''; card.appendChild(img); card.appendChild(nm); r.reel.appendChild(card); } r.chosen = {idx: chosenIdx, weapon: chosenW}; }); // Play ticks const tick = document.getElementById('spin-sound'); let tickTimer = setInterval(()=>{ try{ tick.currentTime = 0; tick.play(); }catch(e){} }, 140); // Animate each reel with slight stagger const animPromises = reels.map((r, i)=> new Promise(resolve => { const wrapRect = r.wrap.getBoundingClientRect(); const markerX = wrapRect.width/2; const targetOffset = r.chosen.idx*cardW + cardW/2 - markerX; const dur = durationBase + i*200 + Math.floor(Math.random()*300); r.reel.classList.add('spinning'); r.reel.style.transition = 'none'; r.reel.style.transform = 'translateX(0px)'; void r.reel.offsetWidth; r.reel.style.transition = `transform ${dur}ms cubic-bezier(0.08, 0.7, 0.12, 1)`; r.reel.style.transform = `translateX(-${targetOffset}px)`; setTimeout(()=>{ r.reel.classList.remove('spinning'); resolve(); }, dur + 30); })); await Promise.all(animPromises); clearInterval(tickTimer); // Show winners as cards; clicking opens lightbox reels.forEach(r=>{ const w = r.chosen.weapon; const card = document.createElement('div'); card.className = 'csgo-win-card ' + (w.tier && w.tier.startsWith('Tier 2') ? 't2':'t1'); const img = document.createElement('img'); img.src = w.img || ''; img.alt = w.name || ''; img.addEventListener('click', ()=>openLightbox(img.src, w.name)); const nm = document.createElement('div'); nm.className = 'name'; nm.textContent = w.name || ''; card.appendChild(img); card.appendChild(nm); winnersWrap.appendChild(card); }); } // Re-bind Spin button (function(){ const spinBtn = Array.from(document.querySelectorAll('button')).find(b=>b.textContent.trim().toLowerCase()==='spin'); if(spinBtn){ spinBtn.removeAttribute('onclick'); spinBtn.addEventListener('click', spinCSGO); } })(); // ---- Spotlight Reveal Randomizer ---- function poolForTier(tier){ const pool = []; if(tier === 'tier2' && typeof t2Weapons !== 'undefined' && t2Weapons.length){ t2Weapons.forEach(w=>{ for(let i=0;i<3;i++) pool.push({...w}); }); } if(typeof t1Weapons !== 'undefined' && t1Weapons.length){ t1Weapons.forEach(w=>{ for(let i=0;i<2;i++) pool.push({...w}); }); } return pool; } function casePool(tier){ const raw = casePool_raw(tier); return weightedPoolFrom(raw); } function computeCount(tier){ if(tier === 'test') return 2; if(tier === 'tier1') return 4; if(tier === 'tier2') return 6; return 2; } function pick(pool){ return pool[Math.floor(Math.random()*pool.length)]; } function openWinnerCard(w, winnersWrap){ const card = document.createElement('div'); card.className = 'win-card ' + (w.tier && w.tier.startsWith('Tier 2') ? 't2':'t1'); const img = document.createElement('img'); img.src = w.img || ''; img.alt = w.name || ''; img.addEventListener('click', ()=>openLightbox(img.src, w.name)); const nm = document.createElement('div'); nm.className='name'; nm.textContent = w.name || ''; card.appendChild(img); card.appendChild(nm); winnersWrap.appendChild(card); } async function spinSpotlight(){ const tier = document.getElementById('randomize-tier-select')?.value || 'tier1'; const stageCard = document.getElementById('spotlight-card'); const imgEl = document.getElementById('spotlight-img'); const nameEl = document.getElementById('spotlight-name'); const winnersWrap = document.getElementById('spotlight-winners'); winnersWrap.innerHTML = ''; const pool = poolForTier(tier); if(!pool.length){ winnersWrap.textContent = 'No items available.'; return; } const count = computeCount(tier); // optional: prevent duplicate immediate repeats let lastName = null; for(let i=0;isetTimeout(r, 900)); // reveal time openWinnerCard(w, winnersWrap); await new Promise(r=>setTimeout(r, 280)); // small pause between reveals } } // Bind Spin button to spotlight (function(){ const spinBtn = Array.from(document.querySelectorAll('button')).find(b=>b.textContent.trim().toLowerCase()==='spin'); if(spinBtn){ spinBtn.removeAttribute('onclick'); spinBtn.addEventListener('click', spinSpotlight); } })(); // -------- One-by-one compact case spinner -------- function casePool_raw(tier){ const pool = []; if(tier === 'refill' && typeof t1Weapons !== 'undefined' && t1Weapons.length){ // Refill: only t1 weapons t1Weapons.forEach(w=>{ pool.push({...w}); }); } else { if(tier === 'tier2' && typeof t2Weapons !== 'undefined' && t2Weapons.length){ t2Weapons.forEach(w=>{ for(let i=0;i<3;i++) pool.push({...w}); }); } if(typeof t1Weapons !== 'undefined' && t1Weapons.length){ t1Weapons.forEach(w=>{ for(let i=0;i<2;i++) pool.push({...w}); }); } } return pool; } function casePool(tier){ const raw = casePool_raw(tier); return weightedPoolFrom(raw); } function caseCount(tier){ if(tier === 'test') return 2; if(tier === 'tier1') return 4; if(tier === 'tier2') return 6; if(tier === 'refill') return 1; return 2; } function pick(pool){ return pool[Math.floor(Math.random()*pool.length)]; } function openWinCard(w){ const winners = document.getElementById('case-winners'); const card = document.createElement('div'); card.className = 'win-card ' + (w.tier && w.tier.startsWith('Tier 2') ? 't2':'t1'); const img = document.createElement('img'); img.src = w.img || ''; img.alt = w.name || ''; img.addEventListener('click', ()=>openLightbox(img.src, w.name)); const nm = document.createElement('div'); nm.className='name'; nm.textContent = w.name || ''; card.appendChild(img); card.appendChild(nm); winners.appendChild(card); } // REPLACED with accurate version function buildReel_old(pool){ const reel = document.getElementById('case-reel'); reel.innerHTML = ''; const tiles = 90; let chosenIdx = Math.floor(tiles*0.65 + Math.random()*14); let chosen = null; for(let i=0;isetTimeout(r, ms+40)); } async function spinCaseOneByOne(){ const tier = document.getElementById('randomize-tier-select').value; const winners = document.getElementById('case-winners'); winners.innerHTML=''; const pool = casePool(tier); if(!pool.length){ winners.textContent='No items available.'; return; } const count = caseCount(tier); let lastName = null; for(let i=0;i{ try{ snd.currentTime=0; snd.play(); }catch(e){} }, 120); await animateReelAccurate(reel, items, chosenIdx, ms); clearInterval(tickTimer); let w = chosen || pick(pool); // If duplicate and we're NOT allowing it this time, nudge to nearest different card if(lastName && w.name===lastName && Math.random() > DUPLICATE_CHANCE){ // find nearest index with a different name let bestIdx = null; for(let delta=1; delta= 0 && items[left].w.name !== lastName){ bestIdx = left; break; } } if(bestIdx != null){ // micro-slide to that card so it matches the visual landing const track = document.querySelector('.case-track'); const rect = track.getBoundingClientRect(); const el = items[bestIdx].el; const target = el.offsetLeft + el.getBoundingClientRect().width/2 - rect.width/2; reel.style.transition = `transform 380ms cubic-bezier(0.12, 0.7, 0.1, 1)`; reel.style.transform = `translate3d(-${Math.max(0, target)}px,0,0)`; await new Promise(r=>setTimeout(r, 400)); w = items[bestIdx].w; } } lastName = w.name; openWinCard(w); await new Promise(r=>setTimeout(r, 160)); // tiny pause before next pick } } // Bind Spin to this new flow (function(){ const spinBtn = Array.from(document.querySelectorAll('button')).find(b=>b.textContent.trim().toLowerCase()==='spin'); if(spinBtn){ spinBtn.removeAttribute('onclick'); spinBtn.addEventListener('click', spinCaseOneByOne); } })(); function buildReel(pool){ const reel = document.getElementById('case-reel'); reel.innerHTML = ''; const tiles = 90; const items = []; for(let i=0;isetTimeout(r, ms+40)); } // ---- Rarity weighting + low-dup logic ---- // Edit this map to set each weapon's rarity: 'grey' | 'green' | 'blue' | 'purple' // Defaults to 'grey' (common) if a name is not listed here. const rarityMap = { 'Glock 19':'grey', 'Glock 17':'grey', 'Glock 17 Gen 5':'blue', 'Glock 19x':'grey', 'Sig P320':'grey', 'Walther p88':'grey', 'Olive g19x':'green', 'Olive glock 17':'grey', 'Glock 19 Foregrip':'grey', 'Hk45':'grey', 'Glock 45':'grey', 'Glock 23':'grey', 'Glock 43':'grey', 'Fn 57':'purple', // example: make rarer than grey 'Canik':'green', // example: uncommon 'G26':'green', // example: uncommon '1911':'purple' // example: rarest }; const rarityWeight = { grey: 6, green: 4, blue: 3, purple: 2 }; // higher = more common function rarityOf(name){ const r = rarityMap[name]; return (r==='green'||r==='blue'||r==='purple') ? r : 'grey'; } function weightedPoolFrom(list){ const out = []; list.forEach(w=>{ const r = rarityOf(w.name); const k = rarityWeight[r] || rarityWeight.grey; for(let i=0;i ~15% chance. const DUPLICATE_CHANCE = 0.22;